import 'package:flutter/material.dart';

import 'app_onstrained_box.dart';

class AppPopupContainer extends StatelessWidget {
  const AppPopupContainer({
    Key? key,
    this.alignment,
    this.removeLeftPadding = true,
    this.removeTopPadding = true,
    this.removeRightPadding = true,
    this.removeBottomPadding = true,
    this.applyBottomViewPadding = false,
    this.backgroundColor,
    this.borderRadius,
    this.minWidthFactor,
    this.minHeightFactor,
    this.widthFactor,
    this.heightFactor,
    this.maxWidthFactor,
    this.maxHeightFactor,
    required this.child,
  })  : assert(minWidthFactor == null || minWidthFactor >= 0.0),
        assert(minHeightFactor == null || minHeightFactor >= 0.0),
        assert(widthFactor == null || widthFactor >= 0.0),
        assert(heightFactor == null || heightFactor >= 0.0),
        assert(maxWidthFactor == null || maxWidthFactor >= 0.0),
        assert(maxHeightFactor == null || maxHeightFactor >= 0.0),
        super(key: key);

  factory AppPopupContainer.center({
    Color? backgroundColor,
    BorderRadius? borderRadius = const BorderRadius.all(Radius.circular(8.0)),
    double? widthFactor = 310.0 / 375.0,
    required Widget child,
  }) {
    return AppPopupContainer(
      alignment: Alignment.center,
      backgroundColor: backgroundColor,
      borderRadius: borderRadius,
      widthFactor: widthFactor,
      child: child,
    );
  }

  factory AppPopupContainer.bottom({
    bool removeBottomPadding = false,
    bool applyBottomViewPadding = true,
    BorderRadius? borderRadius =
        const BorderRadius.vertical(top: Radius.circular(12.0)),
    double? maxHeightFactor = 2.0 / 3.0,
    required Widget child,
  }) {
    return AppPopupContainer(
      removeBottomPadding: removeBottomPadding,
      applyBottomViewPadding: applyBottomViewPadding,
      borderRadius: borderRadius,
      maxHeightFactor: maxHeightFactor,
      child: child,
    );
  }

  /// 宽度百分比
  final AlignmentGeometry? alignment;
  final bool removeLeftPadding;
  final bool removeTopPadding;
  final bool removeRightPadding;
  final bool removeBottomPadding;
  // 是否填充bottomPadding，阻止内容溢出到SafeArea外
  final bool applyBottomViewPadding;
  final Color? backgroundColor;
  final BorderRadius? borderRadius;

  /// 若使用的是[showModalBottomSheet]，由于maxHeight默认为9 / 16，超出需配置isScrollControlled为true
  ///
  /// ```dart
  /// return BoxConstraints(
  ///   minWidth: constraints.maxWidth,
  ///   maxWidth: constraints.maxWidth,
  ///   maxHeight: isScrollControlled
  ///     ? constraints.maxHeight
  ///     : constraints.maxHeight * 9.0 / 16.0,
  /// );
  /// ```
  final double? minWidthFactor;
  final double? minHeightFactor;
  final double? widthFactor;
  final double? heightFactor;
  final double? maxWidthFactor;
  final double? maxHeightFactor;

  final Widget child;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final DialogTheme dialogTheme = DialogTheme.of(context);

    Widget current = child;

    if (!removeBottomPadding && applyBottomViewPadding) {
      final Widget child = current;
      current = Builder(builder: (BuildContext context) {
        final MediaQueryData mediaQuery = MediaQuery.of(context);
        return Padding(
          padding: EdgeInsets.only(bottom: mediaQuery.viewPadding.bottom),
          child: MediaQuery.removePadding(
            context: context,
            removeBottom: true,
            child: child,
          ),
        );
      });
    }

    current = Material(
      color: backgroundColor ??
          dialogTheme.backgroundColor ??
          theme.dialogBackgroundColor,
      shape: borderRadius != null
          ? RoundedRectangleBorder(borderRadius: borderRadius!)
          : null,
      type: MaterialType.card,
      child: current,
    );

    current = FractionallyConstrainedBox(
      minWidthFactor: minWidthFactor,
      minHeightFactor: minHeightFactor,
      widthFactor: widthFactor,
      heightFactor: heightFactor,
      maxWidthFactor: maxWidthFactor,
      maxHeightFactor: maxHeightFactor,
      child: current,
    );

    if (removeLeftPadding ||
        removeTopPadding ||
        removeRightPadding ||
        removeBottomPadding) {
      current = SafeArea(
        left: removeLeftPadding,
        top: removeTopPadding,
        right: removeRightPadding,
        bottom: removeBottomPadding,
        child: current,
      );
    }

    if (alignment != null) {
      current = Align(alignment: alignment!, child: current);
    }

    return current;
  }
}
